﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ft_module_parser
{
    class pvs
    {
        public List<pv> pvList = new List<pv>();
        public List<modules> modulesList = new List<modules>();
        public List<pv_raw> pv_ac = new List<pv_raw>();

        

        public void ParseFT(string files)
        {
            using (StreamReader file = new StreamReader("gm_module.txt"))
            {
                while (file.Peek() >= 0)
                {
                    string line = file.ReadLine();
                    string[] line2 = line.Split('.');
                    int moduleId = int.Parse(line2[1]);

                    var curModule = modulesList.Where(c => c.id == moduleId).FirstOrDefault();
                    if (curModule == null)
                    {
                        modulesList.Add(new modules(moduleId));
                        curModule = modulesList.Where(c => c.id == moduleId).FirstOrDefault();
                    }
                    if (line2[2] != null)
                    {
                        string[] line3 = line2[2].Split('=');
                        if (line3[0] == "cos")
                        {
                            var cos = line3[1].Remove(0, 4);
                            curModule.cos = int.Parse(cos);
                        }
                        if (line3[0] == "chara")
                        {
                            curModule.chara = line3[1].Substring(0, 3);
                        }
                        if (line3[0] == "id")
                        {
                            curModule.actualId = int.Parse(line3[1]);
                        }
                    }

                }
            }

            using (StreamReader file = new StreamReader("pv_db_ac_orig.txt"))
            {
                while (file.Peek() >= 0)
                {
                    string line = file.ReadLine();
                    string[] line2 = line.Split('.');
                    string[] line3 = line2[0].Split('_');

                    int pvid = int.Parse(line3[1]);

                    int lastDiff = 0;

                    var curRawPv = pv_ac.Where(c => c.pvId == pvid).FirstOrDefault();
                    if (curRawPv == null)
                    {
                        pv_ac.Add(new pv_raw(pvid));
                        curRawPv = pv_ac.Where(c => c.pvId == pvid).FirstOrDefault();
                    }
                    curRawPv.rawrows.Add(line);
                }
            }

            using (StreamReader file = new StreamReader(files))
            {
                while (file.Peek() >= 0)
                {
                    string line = file.ReadLine();
                    string[] line2 = line.Split('.');
                    string[] line3 = line2[0].Split('_');

                    int pvid = int.Parse(line3[1]);

                    int lastDiff = 0;

                    var curPv = pvList.Where(c => c.pvId == pvid).FirstOrDefault();
                    if (curPv == null)
                    {
                        pvList.Add(new pv(pvid));
                        curPv = pvList.Where(c => c.pvId == pvid).FirstOrDefault();
                    }
                    try
                    {
                        if (line2[1] != null)
                        {
                            string[] linef = line2[1].Split('=');

                            if (linef[0] == "bpm")
                            {
                                string[] line4 = line2[1].Split('=');
                                curPv.bpm = int.Parse(line4[1]);
                            }

                            if (linef[0] == "date")
                            {
                                string[] line4 = line2[1].Split('=');
                                curPv.date = int.Parse(line4[1]);
                            }

                            if (linef[0] == "song_name_en")
                            {
                                string[] line4 = line2[1].Split('=');
                                curPv.song_name = line4[1];
                            }

                            if (linef[0] == "song_name_reading")
                            {
                                string[] line4 = line2[1].Split('=');
                                curPv.song_name_reading = line4[1];
                            }

                            if (linef[0] == "se_name")
                            {
                                string[] line4 = line2[1].Split('=');
                                curPv.se_name = line4[1];
                            }

                            if (linef[0] == "song_file_name")
                            {
                                string[] line4 = line2[1].Split('=');
                                curPv.song_file = line4[1];
                            }

                            if (line2[1] == "motion")
                            {
                                string[] line4 = line2[2].Split('=');
                                curPv.motions.Add(new motion(int.Parse(line4[0]), line4[1]));
                            }

                            if (line2[1] == "motion2P")
                            {
                                string[] line4 = line2[2].Split('=');
                                curPv.motions2p.Add(new motion(int.Parse(line4[0]), line4[1]));
                            }

                            if (line2[1] == "sabi")
                            {
                                string[] line9 = line2[2].Split('=');
                                if (line9[0] == "play_time")
                                {
                                    curPv.sabiplaytime = line9[1] + "." + line2[3];
                                }
                                if (line9[0] == "start_time")
                                {
                                    curPv.sabistarttime = line9[1] + "." + line2[3];
                                }
                            }

                            if (line2[1] == "songinfo_en")
                            {
                                string[] line9 = line2[2].Split('=');
                                if (line9[0] == "arranger")
                                    curPv.songinfo_arranger = line9[1];

                                if (line9[0] == "illustrator")
                                    curPv.songinfo_illustrator = line9[1];

                                if (line9[0] == "arranger")
                                    curPv.songinfo_lyrics = line9[1];

                                if (line9[0] == "music")
                                    curPv.songinfo_music = line9[1];

                                if (line9[0] == "pv_editor")
                                    curPv.songinfo_pv_editor = line9[1];
                            }

                            if (line2[1] == "field")
                            {
                                curPv.field.Add(line);
                            }

                            if (line2[1].Contains("edit"))
                            {
                                curPv.rawrows.Add(line);
                            }

                            if (line2[1].Contains("osage"))
                            {
                                curPv.osage.Add(line);
                            }

                            if (line2[1].Contains("stage_param"))
                            {
                                curPv.stage_param.Add(line);
                            }

                            if (line2.Contains("title_image"))
                            {
                                curPv.title_image.Add(line);
                            }

                            if (line2.Contains("disp2d"))
                            {
                                curPv.disp2dn.Add(line);
                            }

                            if (line.Contains("hand_item"))
                            {
                                curPv.hand_item.Add(line);
                            }

                            /*
                            if (line2[1] == "disp2d")
                            {
                                string[] line4 = line2[2].Split('=');
                                curPv.disp2d = int.Parse(line4[1]);
                            }*/

                            if (line2[1] == "lyric_en")
                            {
                                string[] line4 = line2[2].Split('=');
                                string rawRow = "";
                                int i = 3;
                                while (i < line2.Length)
                                {
                                    if (i == 3)
                                        rawRow = "." + line2[i];
                                    else rawRow = rawRow + "." + line2[i];
                                    i++;
                                }
                                curPv.lyrics.Add(new lyric(int.Parse(line4[0]), line4[1] + rawRow));
                            }

                            if (line2[1] == "difficulty")
                            {
                                difficulty curDiff = null;
                                if (line2[2] == "easy")
                                {
                                    var type = 0;
                                    curDiff = curPv.difficulties.Where(c => c.type == type).FirstOrDefault();
                                    if (curDiff == null)
                                    {
                                        curPv.difficulties.Add(new difficulty(type));
                                        curDiff = curPv.difficulties.Where(c => c.type == type).FirstOrDefault();
                                    }
                                    lastDiff = type;
                                }
                                else
                                if (line2[2] == "normal")
                                {
                                    var type = 1;
                                    curDiff = curPv.difficulties.Where(c => c.type == type).FirstOrDefault();
                                    if (curDiff == null)
                                    {
                                        curPv.difficulties.Add(new difficulty(type));
                                        curDiff = curPv.difficulties.Where(c => c.type == type).FirstOrDefault();
                                    }
                                    lastDiff = type;
                                }
                                else
                                if (line2[2] == "hard")
                                {
                                    var type = 2;
                                    curDiff = curPv.difficulties.Where(c => c.type == type).FirstOrDefault();
                                    if (curDiff == null)
                                    {
                                        curPv.difficulties.Add(new difficulty(type));
                                        curDiff = curPv.difficulties.Where(c => c.type == type).FirstOrDefault();
                                    }
                                    lastDiff = type;
                                }
                                else
                                if (line2[2] == "extreme")
                                {
                                    var type = 3;
                                    curDiff = curPv.difficulties.Where(c => c.type == type).FirstOrDefault();
                                    if (curDiff == null)
                                    {
                                        curPv.difficulties.Add(new difficulty(type));
                                        curDiff = curPv.difficulties.Where(c => c.type == type).FirstOrDefault();
                                    }
                                    lastDiff = type;
                                }
                                else
                                if (line2[2] == "encore")
                                {
                                    var type = 4;
                                    curDiff = curPv.difficulties.Where(c => c.type == type).FirstOrDefault();
                                    if (curPv == null)
                                    {
                                        curPv.difficulties.Add(new difficulty(type));
                                        curDiff = curPv.difficulties.Where(c => c.type == type).FirstOrDefault();
                                    }
                                    lastDiff = type;
                                }

                                if (curDiff != null)
                                {
                                    string[] line4 = new string[1];
                                    try
                                    {
                                        line4 = line2[4].Split('=');
                                    }
                                    catch
                                    {
                                        try
                                        {
                                            line4 = line2[3].Split('=');
                                        }
                                        catch
                                        {

                                        }
                                    }

                                    if (line4[0] == "script_format")
                                    {
                                        curDiff.script_format = line4[1];
                                    }
                                    if (line4[0] == "version")
                                    {
                                        curDiff.version = int.Parse(line4[1]);
                                    }
                                    if (line4[0] == "level")
                                    {
                                        var ftlevelparse = line4[1].Split('_');
                                        curDiff.level = int.Parse(ftlevelparse[2]);
                                    }
                                    if (line4[0] == "script_file_name")
                                    {
                                        curDiff.script_file = line4[1];
                                    }
                                    if (line2[4] == "motion")
                                    {
                                        var line5 = line2[5].Split('=');
                                        curDiff.motions.Add(new motion(int.Parse(line5[0]), line5[1]));
                                    }
                                    if (line2[4] == "motion2P")
                                    {
                                        var line5 = line2[5].Split('=');
                                        curDiff.motions.Add(new motion(int.Parse(line5[0]), line5[1]));
                                    }
                                    if (line2[4] == "field")
                                    {
                                        string rawRow = "";
                                        int i = 4;
                                        while (i < line2.Length)
                                        {
                                            if (i == 4)
                                                rawRow = rawRow + line2[i];
                                            else rawRow = rawRow + "." + line2[i];
                                            i++;
                                        }
                                        curDiff.field.Add(rawRow);
                                    }
                                }
                            }
                        }
                        if (line2[3] != null)
                        {
                            string[] line4 = line2[3].Split('=');
                            if (line4[0] == "chara")
                            {
                                int modnum = int.Parse(line2[2]);
                                if (modnum == 0)
                                {
                                    curPv.chara1 = line4[1];
                                }
                                if (modnum == 1)
                                {
                                    curPv.chara2 = line4[1];
                                }
                            }
                            if (line4[0] == "pv_costume")
                            {
                                int modnum = int.Parse(line2[2]);
                                if (modnum == 0)
                                {
                                    curPv.cosId = int.Parse(line4[1]);
                                    var curModule = modulesList.Where(c => c.cos == int.Parse(line4[1])).Where(c => c.chara == curPv.chara1).FirstOrDefault();
                                    if (curModule != null)
                                        curPv.moduleEquip = curModule.actualId;
                                }
                                if (modnum == 1)
                                {
                                    curPv.cosId = int.Parse(line4[1]);
                                    var curModule = modulesList.Where(c => c.cos == int.Parse(line4[1])).Where(c => c.chara == curPv.chara2).FirstOrDefault();
                                    if (curModule != null)
                                    {
                                        curPv.moduleEquip2 = curModule.actualId;
                                    }
                                    else
                                    {
                                        curModule = modulesList.Where(c => c.cos == int.Parse(line4[1])).Where(c => c.chara == curPv.chara1).FirstOrDefault();
                                        if (curModule != null)
                                        {
                                            curPv.moduleEquip2 = curModule.actualId;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch
                    {

                    }
                }
            }
        }

        public void SaveToJson()
        {
            JsonSerializer serializer = new JsonSerializer();
            using (StreamWriter sw = new StreamWriter(@"json_pvdb.txt"))
            using (JsonWriter writer = new JsonTextWriter(sw))
            {
                serializer.Serialize(writer, pvList);
            }
        }

        public void SaveToA(string filename)
        {
            using (StreamWriter sw = new StreamWriter(filename))
            {
                foreach (var pv in pvList)
                {
                    string header = "pv_" + string.Format("{0:000}", pv.pvId);
                    var search_ac = pv_ac.Where(c => c.pvId == pv.pvId).FirstOrDefault();
                    if (search_ac != null)
                    {
                        foreach (var i in search_ac.rawrows)
                        {
                            if ((i.Contains(".lyric."))  && (pv.lyrics.Count != 0))
                            {
                                    if (!search_ac.lyrics_written)
                                    {
                                        foreach (var u in pv.lyrics)
                                        {
                                            sw.WriteLine(header + ".lyric." + string.Format("{0:00}", u.index) + "=" + u.text);
                                        }
                                        search_ac.lyrics_written = true;
                                    }
                            }
                            else
                            {
                                if (i.Contains(".song_name=") && (pv.song_file != null))
                                {
                                    var c = i.Split('=');
                                    c[1] = pv.song_name;
                                    sw.WriteLine(c[0] + "=" + c[1]);
                                }
                                else if (i.Contains(".songinfo.arranger") && (pv.song_name_reading != null))
                                {
                                    var c = i.Split('=');
                                    c[1] = pv.songinfo_arranger;
                                    sw.WriteLine(c[0] + "=" + c[1]);
                                }
                                else if (i.Contains(".songinfo.illustrator") && (pv.song_name_reading != null))
                                {
                                    var c = i.Split('=');
                                    c[1] = pv.songinfo_illustrator;
                                    sw.WriteLine(c[0] + "=" + c[1]);
                                }
                                else if (i.Contains("songinfo.lyrics") && (pv.song_name_reading != null))
                                {
                                    var c = i.Split('=');
                                    c[1] = pv.songinfo_lyrics;
                                    sw.WriteLine(c[0] + "=" + c[1]);
                                }
                                else if (i.Contains("songinfo.music") && (pv.song_name_reading != null))
                                {
                                    var c = i.Split('=');
                                    c[1] = pv.songinfo_music;
                                    sw.WriteLine(c[0] + "=" + c[1]);
                                }
                                else if (i.Contains("songinfo.pv_editor") && (pv.song_name_reading != null))
                                {
                                    var c = i.Split('=');
                                    c[1] = pv.songinfo_pv_editor;
                                    sw.WriteLine(c[0] + "=" + c[1]);
                                }
                                else sw.WriteLine(i);
                            }
                        }
                    }
                    else
                    {
                        //string header = "pv_" + string.Format("{0:000}", pv.pvId);
                        //bpm
                        sw.WriteLine(header + ".bpm=" + pv.bpm);
                        //date
                        sw.WriteLine(header + ".date=" + pv.date);
                        //difficulty
                        foreach (var i in pv.difficulties)
                        {
                            if (i.script_file != null)
                            {
                                sw.WriteLine(header + ".difficulty." + i.getDifficulty() + ".level=" + i.level);
                                sw.WriteLine(header + ".difficulty." + i.getDifficulty() + ".script_file_name=" + i.script_file + ".dsc");
                                //sw.WriteLine(header + ".difficulty." + i.getDifficulty() + ".script_format=" + i.script_format); use divascriptconv instead
                                sw.WriteLine(header + ".difficulty." + i.getDifficulty() + ".script_format=0x11062018");
                                sw.WriteLine(header + ".difficulty." + i.getDifficulty() + ".version=" + i.version);

                                if (i.motions.Count != 0)
                                {
                                    foreach (var u in i.motions)
                                    {
                                        sw.WriteLine(header + ".difficulty." + i.getDifficulty() + ".motion." + string.Format("{0:00}", u.index) + "=" + u.text);
                                    }
                                }

                                if (i.field.Count != 0)
                                {
                                    foreach (var u in i.field)
                                    {
                                        sw.WriteLine(header + ".difficulty." + i.getDifficulty() + "." + u);
                                    }
                                }
                            }
                        }
                        //disp2d
                        foreach (var i in pv.disp2dn)
                            sw.WriteLine(i);
                        //sw.WriteLine(header + ".disp2d.set_name=" + pv.disp2d);
                        //hand_item
                        foreach (var i in pv.hand_item)
                            sw.WriteLine(i);
                        //duet
                        if (pv.chara2 != null)
                        {
                            sw.WriteLine(header + ".duet.num=2");
                            sw.WriteLine(header + ".duet.type=USER_SETTING");
                        }
                        //field
                        foreach (var i in pv.field)
                        {
                            sw.WriteLine(i);
                        }
                        //lyric
                        foreach (var i in pv.lyrics)
                        {
                            sw.WriteLine(header + ".lyric." + string.Format("{0:00}", i.index) + "=" + i.text);
                        }
                        //motions
                        foreach (var i in pv.motions)
                        {
                            sw.WriteLine(header + ".motion." + string.Format("{0:00}", i.index) + "=" + i.text);
                        }
                        //motions2P
                        foreach (var i in pv.motions2p)
                        {
                            sw.WriteLine(header + ".motion2P." + string.Format("{0:00}", i.index) + "=" + i.text);
                        }
                        //osage
                        foreach (var i in pv.osage)
                            sw.WriteLine(i);
                        //edits
                        foreach (var i in pv.rawrows)
                        {
                            sw.WriteLine(i);
                        }
                        //sabis
                        if (pv.sabiplaytime != null)
                            sw.WriteLine(header + ".sabi.play_time=" + pv.sabiplaytime);
                        if (pv.sabistarttime != null)
                            sw.WriteLine(header + ".sabi.start_time=" + pv.sabistarttime);
                        //se_name
                        if (pv.se_name != null)
                            sw.WriteLine(header + ".se_name=" + pv.se_name);
                        //song stuff
                        if (pv.song_file != null)
                            sw.WriteLine(header + ".song_file_name=" + pv.song_file + ".ogg");
                        if (pv.song_file != null)
                            sw.WriteLine(header + ".song_name=" + pv.song_name);
                        if (pv.song_name_reading != null)
                            sw.WriteLine(header + ".song_name_reading=" + pv.song_name_reading);
                        if (pv.songinfo_arranger != null)
                            sw.WriteLine(header + ".songinfo.arranger=" + pv.songinfo_arranger);
                        if (pv.songinfo_illustrator != null)
                            sw.WriteLine(header + ".songinfo.illustrator=" + pv.songinfo_illustrator);
                        if (pv.songinfo_lyrics != null)
                            sw.WriteLine(header + ".songinfo.lyrics=" + pv.songinfo_lyrics);
                        if (pv.songinfo_music != null)
                            sw.WriteLine(header + ".songinfo.music=" + pv.songinfo_music);
                        if (pv.songinfo_pv_editor != null)
                            sw.WriteLine(header + ".songinfo.pv_editor=" + pv.songinfo_pv_editor);
                        //stage_param
                        foreach (var i in pv.stage_param)
                            sw.WriteLine(i);
                        //title image aet
                        if (pv.title_image_aet != null)
                            sw.WriteLine(header + ".title_image.aet_name=" + pv.title_image_aet);
                        if (pv.title_image_time != null)
                            sw.WriteLine(header + ".title_image.time=" + pv.title_image_time);
                        //equips
                        if (pv.chara1 != null)
                            sw.WriteLine(header + ".unlock1P=" + pv.chara1);
                        if (pv.chara2 != null)
                            sw.WriteLine(header + ".unlock2P=" + pv.chara2);
                    }
                }
            }
            using (StreamWriter sw = new StreamWriter("pv_modules.csv"))
            {
                foreach (var pv in pvList)
                {
                    int modnum0 = -1;
                    if (pv.moduleEquip != 0)
                        modnum0 = pv.moduleEquip;
                    sw.WriteLine(pv.pvId + "," + modnum0 + "," + pv.moduleEquip2);
                }
            }
        }
    }
}
